﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;

namespace LEE.Tools.IO
{
    public static class FtpHelper
    {
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="fileData">文件数据</param>
        /// <param name="targetFilePath">目标路径</param>
        /// <param name="hostname">ftp地址</param>
        /// <param name="username">ftp用户名</param>
        /// <param name="password">ftp密码</param>
        public static void UploadFile(byte[] fileData, string targetFilePath, string hostname, string username, string password)
        {
            //1. check target
            if (string.IsNullOrWhiteSpace(targetFilePath))
            {
                return;
            }

            var uri = "FTP://" + hostname + "/" + targetFilePath;
            var ftp = GetRequest(uri, username, password);
            ftp.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
            //指定文件传输的数据类型
            ftp.UseBinary = true;
            ftp.UsePassive = true;
            //告诉ftp文件大小
            ftp.ContentLength = fileData.Length;

            //把上传的文件写入流
            using (var rs = ftp.GetRequestStream())
            {
                rs.Write(fileData, 0, fileData.Length);
            }
        }

        /// <summary>
        /// 下载文件到流
        /// </summary>
        /// <param name="stream">流</param>
        /// <param name="ftpFilePath">ftp目标文件路径</param>
        /// <param name="hostname">ftp地址即IP</param>
        /// <param name="username">ftp用户名</param>
        /// <param name="password">ftp密码</param>
        public static void DownloadFile(Stream stream, string ftpFilePath, string hostname, string username, string password)
        {
            var uri = "FTP://" + hostname + "/" + ftpFilePath;
            var ftp = GetRequest(uri, username, password);
            ftp.Method = WebRequestMethods.Ftp.DownloadFile;
            ftp.UseBinary = true;
            ftp.UsePassive = false;

            using (var response = (FtpWebResponse)ftp.GetResponse())
            {
                using (var responseStream = response.GetResponseStream())
                {
                    if (responseStream == null) return;
                    var buffer = new byte[2048];
                    int read;
                    do
                    {
                        read = responseStream.Read(buffer, 0, buffer.Length);
                        stream.Write(buffer, 0, read);
                    } while (read != 0);
                }
            }
        }

        /// <summary>
        /// 搜索远程文件
        /// </summary>
        /// <param name="targetDir"></param>
        /// <param name="hostname"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="SearchPattern"></param>
        /// <returns></returns>
        public static List<string> ListDirectory(string targetDir, string hostname, string username, string password, string SearchPattern)
        {
            try
            {
                var result = new List<string>();
                var uri = "FTP://" + hostname + "/" + targetDir + "/" + SearchPattern;
                var ftp = GetRequest(uri, username, password);
                ftp.Method = System.Net.WebRequestMethods.Ftp.ListDirectory;
                ftp.UsePassive = true;
                ftp.UseBinary = true;
                var str = GetStringResponse(ftp);
                str = str.Replace("\r\n", "\r").TrimEnd('\r');
                str = str.Replace("\n", "\r");
                if (str != string.Empty)
                    result.AddRange(str.Split('\r'));

                return result;
            }
            catch
            {
                return new List<string>();
            }
        }

        private static string GetStringResponse(WebRequest ftp)
        {
            //Get the result, streaming to a string
            string result;
            using (var response = (FtpWebResponse)ftp.GetResponse())
            {
                using (var dataStream = response.GetResponseStream())
                {
                    if (dataStream == null) return null;
                    using (var sr = new StreamReader(dataStream, System.Text.Encoding.Default))
                    {
                        result = sr.ReadToEnd();
                        sr.Close();
                    }

                    dataStream.Close();
                }

                response.Close();
            }

            return result;
        }

        /// <summary>
        /// 在ftp服务器上创建目录
        /// </summary>
        /// <param name="dirName">创建的目录名称</param>
        /// <param name="hostname">ftp地址</param>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        public static void MakeDir(string dirName, string hostname, string username, string password)
        {
            var uri = "ftp://" + hostname + "/" + dirName;
            var ftp = GetRequest(uri, username, password);
            ftp.Method = WebRequestMethods.Ftp.MakeDirectory;

            var response = (FtpWebResponse)ftp.GetResponse();
            response.Close();
        }

        /// <summary>
        /// 删除目录
        /// </summary>
        /// <param name="dirName">创建的目录名称</param>
        /// <param name="hostname">ftp地址</param>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        public static void DelDir(string dirName, string hostname, string username, string password)
        {
            var uri = "ftp://" + hostname + "/" + dirName;
            var ftp = GetRequest(uri, username, password);
            ftp.Method = WebRequestMethods.Ftp.RemoveDirectory;
            var response = (FtpWebResponse)ftp.GetResponse();
            response.Close();
        }

        /// <summary>
        /// 文件重命名
        /// </summary>
        /// <param name="currentFilename">当前目录名称</param>
        /// <param name="newFilename">重命名目录名称</param>
        /// <param name="ftpServerIP">ftp地址</param>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        public static void Rename(string currentFilename, string newFilename, string ftpServerIP, string username, string password)
        {
            var fileInf = new FileInfo(currentFilename);
            var uri = "ftp://" + ftpServerIP + "/" + fileInf.Name;
            var ftp = GetRequest(uri, username, password);
            ftp.Method = WebRequestMethods.Ftp.Rename;
            ftp.RenameTo = newFilename;
            var response = (FtpWebResponse)ftp.GetResponse();
            response.Close();
        }

        private static FtpWebRequest GetRequest(string URI, string username, string password)
        {
            //根据服务器信息FtpWebRequest创建类的对象
            var result = (FtpWebRequest)WebRequest.Create(URI);
            //提供身份验证信息
            result.Credentials = new NetworkCredential(username, password);
            //设置请求完成之后是否保持到FTP服务器的控制连接，默认值为true
            result.KeepAlive = false;
            return result;
        }

        /// <summary>
        /// 判断ftp服务器上该目录是否存在
        /// </summary>
        /// <param name="dirName"></param>
        /// <param name="ftpHostIP"></param>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        private static bool FtpIsExistsFile(string dirName, string ftpHostIP, string username, string password)
        {
            var flag = true;
            try
            {
                var uri = "ftp://" + ftpHostIP + "/" + dirName;
                var ftp = GetRequest(uri, username, password);
                ftp.Method = WebRequestMethods.Ftp.ListDirectory;
                var response = (FtpWebResponse)ftp.GetResponse();
                response.Close();
            }
            catch (Exception)
            {
                flag = false;
            }
            return flag;
        }
    }
}
